import React, { ReactNode, useCallback } from "react";
import { User } from "screens/project-list/search-panel";
import { getToken } from "auth-provider";
import { http } from "utils/http";
import { useMount } from "utils";
import { useAsync } from "utils/use-async";
import { FullPageErrorFallback, FullPageLoading } from "components/lib";
import * as authStore from "store/auth.slice";
import { useDispatch, useSelector } from "react-redux";
import { bootstrap, selectUser } from "store/auth.slice";

export interface AuthForm {
  username: string,
  password: string
}

export const bootstrapUser = async () => {
  let user = null;
  const token = getToken();
  if (token) {
    const data = await http("me", { token });
    user = data.user;
  }
  return user;
};


export const AuthProvider = ({ children }: { children: ReactNode }) => {
  const {
    error, isLoading,
    isIdle, isError, run
  } = useAsync<User | null>();

  const dispatch: (...args: unknown[]) => Promise<User> = useDispatch()


  useMount(() => {
    run(dispatch(bootstrap()));
  });

  if (isIdle || isLoading) {
    return <FullPageLoading/>;
  }

  if (isError) {
    return <FullPageErrorFallback error={error}/>;
  }

  return <div children={children}/>
};

export const useAuth = () => {
  const dispatch: (...args: unknown[]) => Promise<User> = useDispatch();
  const user = useSelector(selectUser);
  const login = useCallback((form: AuthForm) => dispatch(authStore.login(form)), [dispatch]);
  const register = useCallback((form: AuthForm) => dispatch(authStore.register(form)), [dispatch]);
  const logout = useCallback(() => dispatch(authStore.logout()), [dispatch]);
  return {
    user, login, register, logout
  };
};


// 自定义context

// const AuthContext = React.createContext<{
//   user: User | null,
//   login: (form: AuthForm) => Promise<void>,
//   register: (form: AuthForm) => Promise<void>,
//   logout: () => Promise<void>
// } | undefined>(undefined);
// AuthContext.displayName = "AuthContext";
//
// export const AuthProvider = ({ children }: { children: ReactNode }) => {
//   const {
//     data: user, error, isLoading,
//     isIdle, isError, run,
//     setData: setUser
//   } = useAsync<User | null>();
//   // const [user, setUser] = useState<User | null>(null)
//   const login = (form: AuthForm) => auth.login(form).then(setUser);
//   const register = (form: AuthForm) => auth.register(form).then(setUser);
//   const logout = () => auth.logout().then(() => setUser(null));
//
//   useMount(() => {
//     run(bootstrapUser());
//   });
//
//   if (isIdle || isLoading) {
//     return <FullPageLoading/>;
//   }
//
//   if (isError) {
//     return <FullPageErrorFallback error={error}/>;
//   }
//
//   return (
//     <AuthContext.Provider children={children} value={{ user, login, register, logout }}/>
//   );
// };

// export const useAuth = () => {
//   const context = React.useContext(AuthContext)
//   if(!context) {
//     throw new Error('useAuth必须在AuthProvider中使用')
//   }
//   return context
// }
